import axios, {AxiosResponse} from 'axios';
import {ElMessage} from 'element-plus';
import {ApiResponse} from '../api/config';
import {getToken, removeToken, setToken} from './storage';
import router from '../router'

// 创建axios实例
const service = axios.create({
    baseURL: '',  // API前缀已经在config.ts文件中添加，这里不需要再设置
    timeout: 15000,
    headers: {
        'Content-Type': 'application/json;charset=utf-8',
    },
});

// 记录是否正在刷新Token
let isRefreshing = false;
// 暂存请求队列
let requestsQueue: Array<{ config: any, resolve: Function, reject: Function }> = [];

// 刷新token
const refreshToken = async () => {
    try {
        const token = getToken();
        if (!token) {
            return false;
        }

        // 调用刷新token的接口
        const response = await axios({
            method: 'post',
            url: '/api/auth/refreshToken',
            headers: {
                'Authorization': `Bearer ${token}`
            }
        });

        if (response.data && response.data.token) {
            // 保存新token
            setToken(response.data.token);
            return true;
        }
        return false;
    } catch (error) {
        console.error('刷新Token失败:', error);
        return false;
    }
};

// 执行暂存的请求
const processQueue = (isSuccess: boolean, newToken?: string) => {
    requestsQueue.forEach(({config, resolve, reject}) => {
        if (isSuccess) {
            // 使用新token
            if (newToken && config.headers) {
                config.headers['Authorization'] = `Bearer ${newToken}`;
            }
            resolve(service(config));
        } else {
            reject(new Error('刷新Token失败'));
        }
    });
    // 清空队列
    requestsQueue = [];
};

// 请求拦截器，添加token和处理请求
service.interceptors.request.use(
    (config) => {
        // 特殊处理认证接口, 不添加Bearer前缀
        const isAuthEndpoint = config.url?.includes('/api/auth/login') || config.url?.includes('/api/auth/register');

        // 标记导出请求
        const isExportRequest = config.url?.includes('/export') && config.responseType === 'blob';
        if (isExportRequest) {
            // 添加标记，方便后续识别
            config.headers = config.headers || {};
            config.headers['X-Export-Request'] = 'true';
        }

        // 特殊处理PUT请求，确保对象数组正确传递
        if (config.method?.toLowerCase() === 'put' && config.data) {
            // 检查是否包含items数组
            if (config.data.items && Array.isArray(config.data.items)) {
                // 处理items数组
            }
        }

        // 针对创建收货单的POST请求，特别记录详细信息
        if (config.method?.toLowerCase() === 'post' && config.url?.includes('/receipts')) {
            if (config.data.orderId) {
                // 确保订单ID是数字类型
                if (typeof config.data.orderId === 'string') {
                    try {
                        config.data.orderId = parseInt(config.data.orderId, 10);
                    } catch (error) {
                        console.error('订单ID转换失败:', error);
                    }
                }
            }

            // 确保收货单明细项中的数值字段都是数字类型
            if (config.data.items && Array.isArray(config.data.items)) {
                config.data.items = config.data.items.map(item => ({
                    ...item,
                    quantity: Number(item.quantity),
                    unitPrice: Number(item.unitPrice),
                    total: Number(item.total)
                }));
            }
        }

        // 获取token
        const token = getToken();

        // 设置Authorization头，根据不同接口设置不同的头部格式
        if (token && config.headers) {
            if (isAuthEndpoint) {
                // 认证接口不添加Bearer前缀
                config.headers['Authorization'] = token;
            } else {
                // 其他接口添加Bearer前缀
                config.headers['Authorization'] = `Bearer ${token}`;
            }
        }

        return config;
    },
    (error) => {
        console.error('[请求错误]', error);
        return Promise.reject(error);
    }
);

// 统一处理响应数据格式
const normalizeResponse = <T>(data: any): ApiResponse<T> => {
    // 如果响应已经符合ApiResponse格式，直接返回
    if (data && typeof data === 'object' && 'code' in data) {
        // 确保success字段存在
        if (!('success' in data)) {
            data.success = data.code === 200;
        }
        return data as ApiResponse<T>;
    }

    // 如果响应不符合标准格式，转换为标准格式
    return {
        code: 200,
        message: '操作成功',
        success: true,
        data: data as T
    };
};

// 响应拦截器，统一处理响应
service.interceptors.response.use(
    (response: AxiosResponse) => {
        // 检查是否为登录API且有错误码
        if (response.config.url?.includes('/api/auth/login') &&
            response.data &&
            response.data.code !== 200) {
            console.warn('登录失败:', response.data);
        }

        // 如果是blob响应类型，直接返回原始响应
        if (response.config.responseType === 'blob') {
            if (response.data instanceof Blob) {
                // 检查是否是JSON类型的错误响应
                if (response.data.type === 'application/json') {
                    return new Promise((resolve, reject) => {
                        const reader = new FileReader();
                        reader.onload = () => {
                            try {
                                const errorData = JSON.parse(reader.result as string);

                                // 如果是错误消息，转换为标准响应格式
                                if (errorData.code && errorData.code !== 200) {
                                    // 对401未授权错误特殊处理
                                    if (errorData.code === 401) {
                                        ElMessage.error(errorData.message || '登录已过期，请重新登录');

                                        // 返回特殊格式以便上层处理
                                        reject({
                                            code: 401,
                                            message: errorData.message || '登录已过期，请重新登录后再尝试导出',
                                            success: false,
                                            data: null
                                        });
                                        return;
                                    }

                                    response.data = normalizeResponse(errorData);
                                    reject(response);
                                } else {
                                    // 如果是正常JSON，也转换为标准响应格式
                                    response.data = normalizeResponse(errorData);
                                    resolve(response);
                                }
                            } catch (e) {
                                // 如果不是有效的JSON，保持blob格式
                                resolve(response);
                            }
                        };
                        reader.readAsText(response.data);
                    });
                }

                // 对于Excel等文件类型的blob，直接返回
                return {
                    ...response,
                    data: {
                        code: 200,
                        message: '导出成功',
                        success: true,
                        data: response.data
                    }
                };
            }
        }

        // 统一处理响应格式但返回原始response对象，只修改data部分
        response.data = normalizeResponse(response.data);
        return response;
    },
    async (error) => {
        // 记录错误信息
        console.error('[响应异常]', error);
        console.error('错误状态码:', error.response?.status);
        console.error('错误详情:', error.response?.data?.message || error.message);
        console.error('完整错误响应:', error.response?.data);
        console.error('请求URL:', error.config?.url);
        console.error('请求方法:', error.config?.method);
        console.error('请求数据:', error.config?.data);

        // 判断请求是否为导出请求
        const isExportRequest = error.config?.headers?.['X-Export-Request'] === 'true' ||
            (error.config?.url?.includes('/export') && error.config?.responseType === 'blob');

        // 提取可能的错误信息
        let errorMessage = error.response?.data?.message || error.message || '请求失败';

        // 处理常见的错误消息格式化
        if (error.response?.data?.error === 'Bad credentials') {
            errorMessage = '用户名或密码错误';
        } else if (error.response?.status === 401) {
            errorMessage = '用户名或密码错误';
        } else if (error.response?.data?.error) {
            errorMessage = error.response.data.error;
        }

        // 构造错误响应
        const errorResponse: ApiResponse<null> = {
            code: error.response?.status || 500,
            message: errorMessage,
            success: false,
            data: null
        };

        // 单独处理登录接口的错误，不弹出通用错误消息
        const isLoginEndpoint = error.config?.url?.includes('/api/auth/login');
        const isRefreshTokenEndpoint = error.config?.url?.includes('/api/auth/refreshToken');

        // 添加重试计数器
        if (!error.config._retryCount) {
            error.config._retryCount = 0;
        }

        // 处理401错误（令牌过期）
        if (error.response?.status === 401 && !isLoginEndpoint && !isRefreshTokenEndpoint) {
            // 如果是导出请求且返回401，直接返回错误，不进行token刷新
            if (isExportRequest) {
                ElMessage.error('导出失败: 登录状态无效，请重新登录后再尝试导出');
                return Promise.reject({
                    code: 401,
                    message: '导出失败: 登录状态无效，请重新登录',
                    success: false,
                    data: null
                });
            }

            // 超过最大重试次数
            if (error.config._retryCount >= 2) {
                removeToken();
                router.replace({
                    path: '/login',
                    query: {redirect: window.location.hash.slice(1)}
                });
                ElMessage.error('登录已过期，请重新登录');
                return Promise.reject(errorResponse);
            }

            // 尝试刷新token
            if (!isRefreshing) {
                isRefreshing = true;

                try {
                    const success = await refreshToken();

                    if (success) {
                        // 刷新成功，重试原请求
                        const newToken = getToken();
                        if (error.config.headers) {
                            error.config.headers['Authorization'] = `Bearer ${newToken}`;
                        }

                        // 处理队列中的请求
                        processQueue(true, newToken || '');
                        isRefreshing = false;

                        // 增加重试计数
                        error.config._retryCount++;

                        // 重试当前请求
                        return service(error.config);
                    } else {
                        // 刷新失败，清除token并跳转登录页
                        processQueue(false);
                        isRefreshing = false;
                        removeToken();

                        router.replace({
                            path: '/login',
                            query: {redirect: window.location.hash.slice(1)}
                        });
                        ElMessage.error('登录已过期，请重新登录');
                    }
                } catch (refreshError) {
                    // 刷新过程出错
                    processQueue(false);
                    isRefreshing = false;
                    removeToken();

                    router.replace({
                        path: '/login',
                        query: {redirect: window.location.hash.slice(1)}
                    });
                    ElMessage.error('登录已过期，请重新登录');
                }
            } else {
                // 正在刷新token，将请求加入队列
                if (isExportRequest) {
                    // 对于导出请求，如果已经在刷新token，不将其加入队列，直接返回错误
                    return Promise.reject({
                        code: 401,
                        message: '正在刷新登录状态，请稍后重试',
                        success: false,
                        data: null
                    });
                }

                // 其他请求加入队列
                return new Promise((resolve, reject) => {
                    requestsQueue.push({
                        config: error.config,
                        resolve,
                        reject
                    });
                });
            }
        }

        // 根据状态码处理错误，但对登录接口特殊处理
        if (error.response && !isLoginEndpoint && error.response.status !== 401) {
            switch (error.response.status) {
                case 403: // 禁止访问
                    ElMessage.error('您没有权限访问此资源');
                    break;
                case 404: // 未找到
                    ElMessage.error('请求的资源不存在');
                    break;
                case 500: // 服务器错误
                    ElMessage.error(error.response.data?.message || '服务器错误，请稍后再试');
                    break;
                default:
                    ElMessage.error(error.response.data?.message || '请求失败');
            }
        } else if (!isLoginEndpoint && !isRefreshTokenEndpoint) {
            // 非登录接口的其他错误处理
            if (error.message === 'Network Error') {
                // 特别处理网络错误
                console.error('网络连接失败，请检查：');
                console.error('1. 后端服务是否已启动在端口8081');
                console.error('2. 是否存在网络连接问题(CORS/防火墙等)');
                console.error('3. 检查Vite代理配置是否正确');

                ElMessage.error({
                    message: '网络连接失败，无法连接到后端服务',
                    duration: 5000
                });
            } else if (error.request) {
                // 请求未收到响应
                ElMessage.error('网络错误，请检查您的网络连接');
            } else {
                // 请求配置错误
                ElMessage.error('请求配置错误');
            }
        }

        return Promise.reject(errorResponse);
    }
);

// 请求方法
const request = <T = any>(config: any): Promise<ApiResponse<T>> => {
    return service(config).then(response => response.data);
};

export default request; 